package com.it;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ShortBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Set;

/**
 * 公共类工具
 */
public class WebUtil {

    public static int byteArrayToInt(byte[] b) {
        return b[3] & 0xFF |
                (b[2] & 0xFF) << 8 |
                (b[1] & 0xFF) << 16 |
                (b[0] & 0xFF) << 24;
    }

    public static byte[] intToByteArray(int a) {
        return new byte[]{
                (byte) ((a >> 24) & 0xFF),
                (byte) ((a >> 16) & 0xFF),
                (byte) ((a >> 8) & 0xFF),
                (byte) (a & 0xFF)
        };
    }

    /**
     * 转换short为byte
     *
     * @param b
     * @param s     需要转换的short
     * @param index
     */
    public static void putShort(byte b[], short s, int index) {
        b[index + 1] = (byte) (s >> 8);
        b[index + 0] = (byte) (s >> 0);
    }

    /**
     * 通过byte数组取到short
     *
     * @param b
     * @param index 第几位开始取
     * @return
     */
    public static short getShort(byte[] b, int index) {
        return (short) (((b[index + 1] << 8) | b[index + 0] & 0xff));
    }

    public static byte[] shortToByteArray(short s) {
        byte[] shortBuf = new byte[2];
        for (int i = 0; i < 2; i++) {
            int offset = (shortBuf.length - 1 - i) * 8;
            shortBuf[i] = (byte) ((s >>> offset) & 0xff);
        }
        return shortBuf;
    }

    /**
     * 小端字节序->大端字节序
     *
     * @param bytes
     * @return
     */
    public static int byteLittleEndianToInt(byte[] bytes) {
        String nubHexStr = "";
        byte[] temp = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            nubHexStr += Integer.toHexString(bytes[bytes.length - i - 1]);
        }
        return Integer.parseInt(nubHexStr, 16);
    }

    /**
     * 小端字节序->大端字节序
     *
     * @param bytes
     * @return
     */
    public static short byteLittleEndianToShort(byte[] bytes) {
        short length = 0;
        //第一种方式
//        String nubHexStr = "";
//        byte[] temp = new byte[bytes.length];
//        for (int i = 0; i < bytes.length; i++) {
//            nubHexStr += Integer.toHexString(bytes[bytes.length - i - 1]);
//        }
//        length = Short.parseShort(nubHexStr, 16);
        //第二种方式
        ByteBuffer byteBuffer = ByteBuffer.wrap(bytes, 0, 2);
        ShortBuffer shortBuffer = byteBuffer.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
        length = shortBuffer.get();
        return length;
    }

    /**
     * 大端字节序->小端字节序
     *
     * @param i
     * @return
     */
    public static byte[] intToMinByteArray(int i) {
        byte[] result = new byte[4];
        //由高位到低位
        result[3] = (byte) ((i >> 24) & 0xFF);
        result[2] = (byte) ((i >> 16) & 0xFF);
        result[1] = (byte) ((i >> 8) & 0xFF);
        result[0] = (byte) (i & 0xFF);
        return result;
    }

    /**
     * 大端字节序->小端字节序
     *
     * @param i
     * @return
     */
    public static byte[] shortToMinByteArray(short i) {
        byte[] result = new byte[2];
        //由高位到低位
        result[1] = (byte) ((i >> 8) & 0xFF);
        result[0] = (byte) (i & 0xFF);
        return result;
    }

    public static String httpRequest(String requestUrl, Map<String, Object> heads, String requestMethod, String requestBody) {
        BufferedOutputStream out = null;
        try {
            URL url = new URL(requestUrl);
            // 打开和URL之间的连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "close");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            //设置读写超时时间
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(30000);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod(requestMethod);
            conn.setRequestProperty("Content-Type", "application/json");

            //若头信息存在，则增加头信息设置，覆盖掉通用配置
            if (heads != null) {
                Set<String> keys = heads.keySet();
                for (String key : keys) {
                    conn.addRequestProperty(key, (String) heads.get(key));
                }
            }

            conn.connect();

            if ("POST".equalsIgnoreCase(requestMethod) && null != requestBody) {
                // 获取URLConnection对象对应的输出流
                out = new BufferedOutputStream(conn.getOutputStream());
                // 发送请求参数
                out.write(requestBody.getBytes());
                // flush输出流的缓冲
                out.flush();
            }

            // 获取所有响应头字段
            //Map<String, List<String>> responseHeaders = conn.getHeaderFields();
            return streamToString(conn.getInputStream());
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        } finally {
            IOUtils.closeQuietly(out);
        }
    }

    private static String streamToString(InputStream in) {
        ByteArrayOutputStream bin = new ByteArrayOutputStream();
        try {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = in.read(buffer)) != -1) {
                bin.write(buffer, 0, length);
            }
            return bin.toString(StandardCharsets.UTF_8.name());
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        } finally {
            IOUtils.closeQuietly(bin);
            IOUtils.closeQuietly(in);
        }
    }

    /**
     * 处理https GET/POST请求
     * 请求地址、请求方法、参数
     **/
    public static String httpsRequest(String requestUrl, Map<String, Object> heads, String requestMethod, String requestBody, TrustManager[] trustManager) {
        BufferedOutputStream out = null;
        try {
            //创建SSLContext
            SSLContext sslContext = SSLContext.getInstance("SSL");
            //初始化
            sslContext.init(null, trustManager, new java.security.SecureRandom());
            //获取SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            URL url = new URL(requestUrl);
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "close");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            //设置读写超时时间
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(30000);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod(requestMethod);
            conn.setRequestProperty("Content-Type", "application/json");

            //若头信息存在，则增加头信息设置，覆盖掉通用配置
            if (heads != null) {
                Set<String> keys = heads.keySet();
                for (String key : keys) {
                    conn.addRequestProperty(key, (String) heads.get(key));
                }
            }

            //设置当前实例使用的SSLSoctetFactory
            conn.setSSLSocketFactory(ssf);
            conn.connect();

            //往服务器端写内容
            if ("POST".equalsIgnoreCase(requestMethod) && !StringUtils.isEmpty(requestBody)) {
                // 获取URLConnection对象对应的输出流
                out = new BufferedOutputStream(conn.getOutputStream());
                // 发送请求参数
                out.write(requestBody.getBytes());
                // flush输出流的缓冲
                out.flush();
            }

            // 获取所有响应头字段
            //Map<String, List<String>> responseHeaders = conn.getHeaderFields();
            //读取服务器端返回的内容
            return streamToString(conn.getInputStream());
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        } finally {
            IOUtils.closeQuietly(out);
        }
    }
//    //byte 数组与 int 的相互转换
//    public static int byteArrayToInt(byte[] b) {
//        return   b[3] & 0xFF |
//                (b[2] & 0xFF) << 8 |
//                (b[1] & 0xFF) << 16 |
//                (b[0] & 0xFF) << 24;
//    }
//
//    public static byte[] intToByteArray(int a) {
//        return new byte[] {
//                (byte) ((a >> 24) & 0xFF),
//                (byte) ((a >> 16) & 0xFF),
//                (byte) ((a >> 8) & 0xFF),
//                (byte) (a & 0xFF)
//        };
//    }




}
